package com.huilian.iotbox.admin.wap.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.huilian.iotbox.admin.wap.dao.QualificationDao;
import com.huilian.iotbox.admin.wap.service.BankRegionService;
import com.huilian.iotbox.admin.wap.service.MerchantPayCompanyService;
import com.huilian.iotbox.admin.wap.service.MerchantService;
import com.huilian.iotbox.admin.wap.service.QualificationService;
import com.huilian.iotbox.data.common.ServerResponse;
import com.huilian.iotbox.data.config.AgencyConfig;
import com.huilian.iotbox.data.config.MiddlewareConfig;
import com.huilian.iotbox.data.dto.*;
import com.huilian.iotbox.data.enums.*;
import com.huilian.iotbox.data.po.Merchant;
import com.huilian.iotbox.data.po.MerchantPayCompany;
import com.huilian.iotbox.data.po.Qualification;
import com.huilian.iotbox.data.properties.ConfigProperties;
import com.huilian.iotbox.data.utils.HttpUtils;
import com.huilian.iotbox.data.utils.HttpsMain;
import com.huilian.iotbox.data.vo.MerchantVo;
import com.huilian.iotbox.data.vo.QualificationVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.*;

/**
 * @author 谢洛涛
 * @date 2021/3/23 10:12
 */
@Slf4j
@Service
public class QualificationServiceImpl implements QualificationService {
    @Resource
    private QualificationDao qualificationDao;
    @Autowired
    private BankRegionService bankRegionService;
    @Autowired
    private MerchantService merchantService;
    @Resource
    private ConfigProperties configProperties;
    @Autowired
    private MerchantPayCompanyService merchantPayCompanyService;
    @Autowired
    private AgencyConfig agencyConfig;

    @Override
    public Integer addQualification(Qualification qualification) {
        return qualificationDao.addQualification(qualification);
    }

    @Override
    public PageInfo findQualificationList(Qualification qualification) {
        PageHelper.startPage(qualification.getPageNum(), qualification.getPageSize());
        List<Qualification> qualificationList = qualificationDao.findQualificationList(qualification);
        PageInfo pageInfo = new PageInfo(qualificationList);
        return pageInfo;
    }

    @Override
    public ServerResponse findQualificationInfo(Qualification qualification) throws Exception {

        if (StringUtils.isEmpty(qualification.getCertNo())) {
            return ServerResponse.createByErrorMessage("资质编号不能为空");
        }

        if (StringUtils.isEmpty(qualification.getId())) {
            return ServerResponse.createByErrorMessage("资质ID不能为空");
        }

        Map<String, Object> form = new HashMap<>();
        form.put("certNo", qualification.getCertNo());
        String param = HttpUtils.format(agencyConfig, form, FunctionEnum.HL_QUALIFICATION_QUERY, PayCompanyEnum.HELIPAY.getCode());
        String response = HttpsMain.httpsReq(MiddlewareConfig.merchantInfo, param);
        final Map<String, Object> result = HttpUtils.getResultData(response);
        log.info("响应报文result: {}", result);
        if (RequestStatus.SUCCESS.getCode().equals(result.get("status")) && RequestStatus.SUCCESS_CODE.getCode().equals(result.get("code"))) {
            Map<String, Object> resMap = (Map<String, Object>) result.get("data");
            Map<String, Object> res = (Map<String, Object>) resMap.get("hlQualification");
            Map<String, String> hlQualificationBankCard = (Map<String, String>) res.get("hlQualificationBankCard");
            QualificationVo qualificationVo = new QualificationVo();
            qualificationVo.setId(qualification.getId());
            qualificationVo.setCertNo((String) res.get("certNo"));
            qualificationVo.setMerchantType((String) res.get("merchantType"));
            qualificationVo.setDealType(Integer.getInteger(res.get("dealType").toString()));
            qualificationVo.setPrincipalCertNo((String) res.get("principalCertNo"));
            qualificationVo.setPrincipalPerson((String) res.get("principalPerson"));
            qualificationVo.setLegalPerson((String) res.get("legalPerson"));
            qualificationVo.setAccountType(hlQualificationBankCard.get("accountType"));
            qualificationVo.setBankCardNo(hlQualificationBankCard.get("bankCardNo"));
            qualificationVo.setBankCertName(hlQualificationBankCard.get("bankCertName"));
            qualificationVo.setHeadBankCode(hlQualificationBankCard.get("headBankCode"));
            qualificationVo.setBankCode(hlQualificationBankCard.get("bankCode"));
            qualificationVo.setContactLine(hlQualificationBankCard.get("contactLine"));
            qualificationVo.setBankName(hlQualificationBankCard.get("bankName"));
            qualificationVo.setBranchName(hlQualificationBankCard.get("branchName"));
            qualificationVo.setBankProvince(hlQualificationBankCard.get("branchProvince"));
            qualificationVo.setBankCity(hlQualificationBankCard.get("branchCity"));
            qualificationVo.setCertType(hlQualificationBankCard.get("certType"));
            qualificationVo.setCertNoExpDate(hlQualificationBankCard.get("certNoExpDate"));
            qualificationVo.setCardHolderAddress(hlQualificationBankCard.get("cardHolderAddress"));
            qualificationVo.setBankCardA(hlQualificationBankCard.get("bankCardA"));
            qualificationVo.setBankCardB(hlQualificationBankCard.get("bankCardB"));
            qualificationVo.setHandHoldBankCard(hlQualificationBankCard.get("handHoldBankCard"));
            qualificationVo.setSettlementAuthorization(hlQualificationBankCard.get("settlementAuthorization"));
            String bankRegion = bankRegionService.findBankRegion(qualificationVo.getBankProvince(), qualificationVo.getBankCity());
            qualificationVo.setBankRegion(bankRegion);
            return ServerResponse.createBySuccess(qualificationVo);
        } else {
            return ServerResponse.createByErrorMessage((String) result.get("msg"));
        }
    }

    @Override
    public ServerResponse qualificationRegister(QualificationDto qualificationDto) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException {
        String outTradeNo = null;
        if (StringUtils.isEmpty(qualificationDto.getOutTradeNo())) {
            outTradeNo = UUID.randomUUID().toString();
        } else {
            outTradeNo = qualificationDto.getOutTradeNo();
        }
        MerchantBankCardDto merchantBankCard = new MerchantBankCardDto(
                qualificationDto.getBankCardNo(),   //银行卡号
                qualificationDto.getBankCertName(),  //账户名
                qualificationDto.getAccountType(), //结算类型，01：对私 02：对公
                qualificationDto.getContactLine(),//联行号
                qualificationDto.getBankName(),//银行名称
                qualificationDto.getBankProvince(),//开户行省
                qualificationDto.getBankCity(),//开户行市
                PrincipalCertTypeEnum.IdentityCard.getCertCode(),
                qualificationDto.getPrincipalCertNo(),//身份证号
                qualificationDto.getBankRegion(),//持卡人地址
                qualificationDto.getBankCardA(),//银行卡正面
                qualificationDto.getBankCardB()//银行卡反面
        );
        //merchantDetail 修改时，参数可以不传
//        MerchantDetail merchantDetail = new MerchantDetail();
//        merchantDetail.setPrincipalCertType("01");
//        merchantDetail.setPrincipalCertNo("7945f2f9-3e3-a31c-9c");
        List<MerchantFeeParamDto> feeParamList = new ArrayList<>();
        feeParamList.add(new MerchantFeeParamDto(PayChannelEnum.WX.getChnCode(), MerchantFeeTypeEnum.T1.getFeeCode(), FeeValueEnum.rate.getCode()));
        feeParamList.add(new MerchantFeeParamDto(PayChannelEnum.Ali.getChnCode(), MerchantFeeTypeEnum.T1.getFeeCode(), FeeValueEnum.rate.getCode()));
        MerchantDto merchantDto = new MerchantDto();
//        merchant.setOutTradeNo("b0470b2f-7956-4517-b742-feca1a9af566");
        merchantDto.setOutTradeNo(outTradeNo);
        if (MerchantTypeEnum.Natural.getCode().equals(qualificationDto.getMerchantType())) {
            merchantDto.setMerchantName("商户_" + qualificationDto.getPrincipalPerson());
        } else {
            merchantDto.setMerchantName(qualificationDto.getLegalPerson());
        }
        merchantDto.setMerchantShortName(qualificationDto.getMerchantShortName());

        merchantDto.setMccCode(MccEnum.AirTravel.getMccCode());
        merchantDto.setMerchantType(qualificationDto.getMerchantType());
        merchantDto.setDealType(DealTypeEnum.EntityAndInternet.getDealCode());
        merchantDto.setStlTyp("1");
        merchantDto.setPath(configProperties.getClientBackEndUrl() + "/");
        //资质编号
        merchantDto.setCertNo(qualificationDto.getCertNo());
        int random = (int) (Math.random() * 900 + 100);
        String email = String.valueOf(System.currentTimeMillis()) + random + "@qq.com";
        merchantDto.setEmail(email);

        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(merchantDto), Feature.OrderedField);
        jsonObject.put("merchantBankCard", merchantBankCard);
        jsonObject.put("merchantFeeList", feeParamList);

        String param = HttpUtils.format(agencyConfig, jsonObject, FunctionEnum.QUALIFICATION_REGISTER, qualificationDto.getPayCompanyCode());
        log.info("请求报文: {}", param);
        String response = HttpsMain.httpsReq(MiddlewareConfig.MerchantRegists, param);
        log.info("响应报文: {}", response);
        final Map<String, Object> result = HttpUtils.getResultData(response);
        if (RequestStatus.SUCCESS.getCode().equals(result.get("status")) && RequestStatus.SUCCESS_CODE.getCode().equals(result.get("code"))) {
            Map<String, String> resMap = (Map<String, String>) result.get("data");
            Merchant merchant = new Merchant();
            merchant.setOutTradeNo(outTradeNo);
            MerchantVo merchantVo = merchantService.findMerchantByOutTradeNo(merchant);
            if (StringUtils.isEmpty(merchantVo)) {
                merchant.setQualificationId(qualificationDto.getId());
                merchant.setMerchantId(resMap.get("hlMerchantId"));
                merchant.setPayCompanyCode(qualificationDto.getPayCompanyCode());
                merchant.setFeeValue(FeeValueEnum.rate.getCode());
                merchant.setStatus(MerchantStatusEnum.AUDITING_YIHAO.getCode());
                merchant.setMerchantShortName(merchantDto.getMerchantShortName());
                merchantService.addMerchant(merchant);
                MerchantPayCompany merchantPayCompany = new MerchantPayCompany();
                merchantPayCompany.setMchId(merchant.getId());
                merchantPayCompany.setPayCompanyCode(qualificationDto.getPayCompanyCode());
                merchantPayCompany.setBankCardNo(merchantBankCard.getBankCardNo());
                merchantPayCompany.setBankCertName(merchantBankCard.getBankCertName());
                merchantPayCompanyService.addMerchantPayCompany(merchantPayCompany);
            } else {
                merchant.setStatus(MerchantStatusEnum.AUDITING_YIHAO.getCode());
                merchantService.updateMerchant(merchant);
                MerchantPayCompanyDto merchantPayCompanyDto = new MerchantPayCompanyDto();
                merchantPayCompanyDto.setMchId(merchantVo.getId());
                merchantPayCompanyDto.setPayCompanyCode(merchantDto.getPayCompanyCode());
                merchantPayCompanyDto.setBankCardNo(merchantBankCard.getBankCardNo());
                merchantPayCompanyDto.setBankCertName(merchantBankCard.getBankCertName());
                merchantPayCompanyService.update(merchantPayCompanyDto);
            }
            return ServerResponse.createBySuccess(merchant);
        } else {
            return ServerResponse.createByErrorMessage((String) result.get("msg"));
        }
    }

    @Override
    public ServerResponse findMerchantIdByQualificationId(Qualification qualification) {
        return ServerResponse.createBySuccess(qualificationDao.findMerchantIdByQualificationId(qualification));
    }


    @Override
    public ServerResponse findSubLedgerMerchantCountByUserId(Qualification qualification) {
        Integer count = qualificationDao.findSubLedgerMerchantCountByUserId(qualification);
        Map<String, Object> map = new HashMap<>();
        map.put("count", count);
        return ServerResponse.createBySuccess(map);
    }

    @Override
    public ServerResponse findQualificationByType(Qualification qualification) {
        return ServerResponse.createBySuccess(qualificationDao.findQualificationByType(qualification));
    }

    @Override
    public int updateNameWhereCertNo(Qualification qualification) {
        return qualificationDao.updateNameWhereCertNo(qualification);
    }
}
